package com.myqf.d8_反射.reflect.clazz;


import java.lang.reflect.Constructor;

/**
 * 作者：黎杭
 * 日期：2020/2/19
 */
public class TestConstructor2_无参构造类 {
    public static void main(String[] args) throws Exception {


        // 使用反射的步骤：1拿到User类的反射（Class）类

        Class cls = Member.class;// 这种看起来最简单，所以以后哪个简单就用哪个方法获取反射类

        // 第二步：既然是需要构造一个对象，那么我们需要Constructor对象
        Constructor constructor = cls.getDeclaredConstructor();// 无参构造是没有参数的，所以这里不用传参数
        constructor.setAccessible(true);// 解封
        // constructor 对象当前来说是描述User对象中的构造方法的。
        Object o = constructor.newInstance();// 用构造器去创建对象实例
        // 非要创建呢？
        // 解封操作！

        if (o instanceof Member) {// 如果属于User类的对象，我们可以向下强制转型！
            Member u = (Member) o;// 这样做就是安全的
            u.setName("张三");
            System.err.println(u.getName());
        }
        System.err.println(o instanceof Member);

        // 如果 类里边有公共的无参构造，直接可以创建对象，不必用Constructor来创建
// 反射类直接创建对象。 解封只能够解除用构造器去创建时的 封装，Class类里边的newInstance 还是不能用
        // 所以每个 实体类中必须提供公共的无参构造方法。
        Object o1 = cls.newInstance();

        System.err.println(o1 instanceof Member);
    }

    // 现在的需求是：别人传什么，你就给别人返回什么
    // 举个例子：根据用户id查询用户信息，传进来的时候，只带了一个id而已

    public static Object getObject(Object obj) {
        // 第一步：应该获取Class类
        Class cls = obj.getClass();// 拿到反射类就等于拿到了这个类的一切
        // 可以通过Field类直接把用户传来的ID也取出来
        try {
            // 第二步：根据这个id去数据库查询出数据

            // 创建一个实例（用户），用来保存数据库里边查出来的数据
            Object o = cls.newInstance();// 指的是用户，这个时候还是 没有保存数据的
            // 在这之间我们就可以对这个O，做很多事情了
            // 就需要给属性设置值

            // 给属性设置值
            // 拿到Method对象的话，我们就可以调用 setter方法


            //

            //
            // 根据反射去获取成员和方法，把查询出来的数据，设置给 这个o
            // 回去的时候就带上了查询出来的数据了
            //
            return o;// 最后经过方法或者成员的设置数据，返回的时候就带上了数据了，这个时候这个对象就是要查询的对象
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}
